// --------------------------------------------------------------------------------------------------------------------
// <copyright file="InfiniteMagazine.cs" company="">
//   
// </copyright>
// <summary>
//   The infinite magazine.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace RescueRaiders.Models
{
    using System.Collections.Generic;
    using System.Linq;

    using Microsoft.Xna.Framework;
    using Microsoft.Xna.Framework.Graphics;

    /// <summary>
    /// The infinite magazine.
    /// </summary>
    internal class InfiniteMagazine
    {
        /// <summary>
        /// The max range.
        /// </summary>
        private readonly float maxRange;

        /// <summary>
        /// The texture.
        /// </summary>
        private readonly Texture2D texture;

        /// <summary>
        /// Initializes a new instance of the <see cref="InfiniteMagazine"/> class.
        /// </summary>
        /// <param name="texture">
        /// The texture.
        /// </param>
        /// <param name="maxRange">
        /// The max range.
        /// </param>
        public InfiniteMagazine(Texture2D texture, float maxRange)
        {
            Fired = new HashSet<Ammo>();
            this.texture = texture;
            this.maxRange = maxRange;
        }

        /// <summary>
        /// Gets Fired.
        /// </summary>
        protected ICollection<Ammo> Fired { get; private set; }

        /// <summary>
        /// The collide.
        /// </summary>
        /// <param name="other">
        /// The other.
        /// </param>
        public Vector2 Collide(BaseModel other)
        {
            // base.Collide(other);
            foreach (var ammo in Fired)
            {
                var vector = ammo.Collide(other);
                if (!vector.Equals(Vector2.Zero))
                {
                    return vector;
                }
            }

            return Vector2.Zero;
        }

        /// <summary>
        /// The draw.
        /// </summary>
        /// <param name="spriteBatch">
        /// The sprite batch.
        /// </param>
        /// <param name="cameraX">
        /// The camera x.
        /// </param>
        public void Draw(SpriteBatch spriteBatch, float cameraX)
        {
            foreach (var ammo in Fired)
            {
                ammo.Draw(spriteBatch, cameraX);
            }
        }

        /// <summary>
        /// The fire.
        /// </summary>
        /// <param name="position">
        /// The position.
        /// </param>
        /// <param name="direction">
        /// The direction.
        /// </param>
        /// <param name="rotation">
        /// The rotation.
        /// </param>
        /// <param name="soundEmitter">
        /// The sound emitter.
        /// </param>
        public virtual void Fire(Vector2 position, Vector2 direction, float rotation, Vector3 soundEmitter)
        {
            var ammo = new Ammo(texture, maxRange);
            ammo.Fire(position, direction, rotation, soundEmitter);
            Fired.Add(ammo);
        }

        /// <summary>
        /// The update.
        /// </summary>
        /// <param name="gameTime">
        /// The game time.
        /// </param>
        public void Update(GameTime gameTime)
        {
            // first, update all the ammo
            foreach (var ammo in Fired)
            {
                ammo.Update(gameTime);
            }

            // next, remove ammo that is out of range
            foreach (var ammo in Fired.Where(x => x.RangeLeft < 0).ToList())
            {
                Fired.Remove(ammo);
            }
        }
    }
}